package sk.vasicek.drinkmanager.activity;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import sk.vasicek.drinkmanager.R;
import sk.vasicek.drinkmanager.domain.DrinkItemizedOverlay;
import sk.vasicek.drinkmanager.domain.DrinkPoint;
import sk.vasicek.drinkmanager.domain.Language;
import sk.vasicek.drinkmanager.domain.LocationItemizedOverlay;
import sk.vasicek.drinkmanager.service.BackgroundAdapter;
import sk.vasicek.drinkmanager.service.DrinkPlaceHelper;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;

public class DrinkMapsActivity extends MapActivity implements LocationListener {
	private static String TAG = "DrinkMapsActivity";

	public MapView mapView;

	private int minMillisecondThresholdForLongClick = 800;
	private long startTimeForLongClick = 0;
	private float xScreenCoordinateForLongClick;
	private float yScreenCoordinateForLongClick;
	private float xtolerance = 10;
	private float ytolerance = 10;
	private float xlow;
	private float xhigh;
	private float ylow;
	private float yhigh;
	protected GeoPoint loc;
	protected Dialog dialog;
	protected TextView eventName;
	protected TextView eventDescription;
	protected TextView ratingLabel;
	protected RatingBar eventRating;
	protected Button updateButton;
	protected Button removeButton;

	private int lat;
	private int longitude;
	private MapController mapController;
	LocationManager locationManager = null;
	private LocationItemizedOverlay myPositionOverlay;
	private DrinkItemizedOverlay drinkPointsOverlay;
	private ImageButton myCurrentLocation;
	private boolean showCurrentLocation = false;
	protected ImageButton settingsButton;
	protected ImageButton mapButton;
	protected ImageButton placesButton;
	protected ImageButton drinksButton;

	private DrinkPlaceHelper drinkDatabaseHelper = null;

	private ImageButton saveMyPosition;
	SharedPreferences prefs;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Configuration config = getBaseContext().getResources().getConfiguration();
		Locale locale = Language.getApplicationLanguage(this);
		Locale.setDefault(locale);
		config.locale = locale;
		getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
		setContentView(R.layout.drinkmap);
		Log.d(TAG, "Started DrinkMapsActivity");

		prefs = PreferenceManager.getDefaultSharedPreferences(this);
		BackgroundAdapter.updateBackgroundFromPrefs(prefs, this);
		drinkDatabaseHelper = new DrinkPlaceHelper(getApplicationContext());

		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		Location location = requestLocationProvider(locationManager);

		mapView = (MapView) this.findViewById(R.id.mapView);
		mapView.setBuiltInZoomControls(true);
		mapView.setTraffic(true);
		mapView.setClickable(true);

		if (location != null) {
			OverlayItem overlayItem = getMyPositionOverlayItem(location);
			// mapView.setSatellite(true);
			mapController = mapView.getController();
			mapController.setCenter(overlayItem.getPoint());
			mapController.setZoom(14);

			SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(DrinkMapsActivity.this);
			int backgroundId = Integer.parseInt(prefs.getString("BackgroundPref", "0"));
			Drawable myPositionSign = this.getResources().getDrawable(BackgroundAdapter.getStyle(backgroundId).getCharIcon());
			myPositionOverlay = new LocationItemizedOverlay(myPositionSign, mapView.getContext());
			myPositionOverlay.addOverlay(overlayItem);
		}

		List<Overlay> mapOverlays = mapView.getOverlays();

		updateDrinkPoints();

		int styleId = Integer.parseInt(prefs.getString("BackgroundPref", "0"));
		Drawable myCharSign = this.getResources().getDrawable(BackgroundAdapter.getStyle(styleId).getCharIcon());
		Drawable myPoiSign = this.getResources().getDrawable(BackgroundAdapter.getStyle(styleId).getPoiIcon());

		this.saveMyPosition = (ImageButton) this.findViewById(R.id.saveMyPosition);
		this.saveMyPosition.setImageDrawable(myPoiSign);
		this.saveMyPosition.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Location location = requestLocationProvider(locationManager);
				if (location != null) {
					Date timeOfLocation = new Date(location.getTime());
					drinkDatabaseHelper.insertDrinkMapPoint(
							getResources().getText(R.string.myDrinkPosition) + "",
							getResources().getText(R.string.myPosition) + ": " + String.valueOf(location.getLatitude()).subSequence(0, 6) + " "
									+ String.valueOf(location.getLongitude()).subSequence(0, 6) + " " + timeOfLocation.getDate() + "." + timeOfLocation.getMonth() + ". " + timeOfLocation.getHours()
									+ ":" + timeOfLocation.getMinutes() + ":" + timeOfLocation.getSeconds(), 0.0d, location.getLatitude(), location.getLongitude());
					OverlayItem overlayItem = getMyPositionOverlayItem(location);
					updateDrinkPoints();
					mapController.animateTo(overlayItem.getPoint());
				}
				Toast.makeText(DrinkMapsActivity.this.getApplicationContext(), getResources().getText(R.string.pointSaved), Toast.LENGTH_SHORT).show();
			}
		});

		this.myCurrentLocation = (ImageButton) this.findViewById(R.id.myCurrentLocation);
		this.myCurrentLocation.setImageDrawable(myCharSign);
		this.myCurrentLocation.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Location location = requestLocationProvider(locationManager);
				if (location != null) {

					OverlayItem overlayItem = getMyPositionOverlayItem(location);
					if (mapView.getOverlays().contains(myPositionOverlay))
						mapView.getOverlays().remove(myPositionOverlay);

					SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(DrinkMapsActivity.this);
					int backgroundId = Integer.parseInt(prefs.getString("BackgroundPref", "0"));
					Drawable myPositionSign = DrinkMapsActivity.this.getResources().getDrawable(BackgroundAdapter.getStyle(backgroundId).getCharIcon());
					myPositionOverlay = new LocationItemizedOverlay(myPositionSign, mapView.getContext());
					myPositionOverlay.addOverlay(overlayItem);
					mapView.getOverlays().add(myPositionOverlay);
					mapController.animateTo(overlayItem.getPoint());

					if (showCurrentLocation == true) {
						showCurrentLocation = false;
						Toast.makeText(DrinkMapsActivity.this.getApplicationContext(), getResources().getText(R.string.trackingOffToast), Toast.LENGTH_SHORT).show();
					} else {
						showCurrentLocation = true;
						Toast.makeText(DrinkMapsActivity.this.getApplicationContext(), getResources().getText(R.string.trackingOnToast), Toast.LENGTH_SHORT).show();
					}
				}
			}
		});

		if (locationManager != null && location != null && myPositionOverlay != null && myPositionOverlay.size() > 0) {
			mapOverlays.add(myPositionOverlay);
		}

		// if (locationManager != null && location != null && drinkPointsOverlay
		// != null && drinkPointsOverlay.size() > 0) {
		// mapOverlays.add(drinkPointsOverlay);
		// }

		this.mapButton = (ImageButton) this.findViewById(R.id.map);
		mapButton.setVisibility(View.VISIBLE);
		this.mapButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Toast.makeText(getApplicationContext(), getResources().getText(R.string.alreadyToast), Toast.LENGTH_SHORT).show();

				// Intent intent = new Intent(getApplicationContext(),
				// DrinkMapsActivity.class);
				// startActivity(intent);
			}
		});
		this.placesButton = (ImageButton) this.findViewById(R.id.places);
		placesButton.setVisibility(View.VISIBLE);
		this.placesButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(getApplicationContext(), DrinkPlacesActivity.class);
				startActivity(intent);
			}
		});

		this.settingsButton = (ImageButton) this.findViewById(R.id.settings);
		settingsButton.setVisibility(View.VISIBLE);
		this.settingsButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(getApplicationContext(), SettingsActivity.class);
				startActivity(intent);
			}
		});

		this.drinksButton = (ImageButton) this.findViewById(R.id.drinks);
		this.drinksButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(getApplicationContext(), DrinkManagerListActivity.class);
				startActivity(intent);
				// Toast.makeText(getApplicationContext(),
				// getResources().getText(R.string.alreadyToast),
				// Toast.LENGTH_SHORT).show();

			}
		});
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {

		int actionType = ev.getAction();
		drinkDatabaseHelper = new DrinkPlaceHelper(DrinkMapsActivity.this.getApplicationContext());

		if (actionType == MotionEvent.ACTION_DOWN) {
			startTimeForLongClick = ev.getEventTime();
			xScreenCoordinateForLongClick = ev.getX();
			yScreenCoordinateForLongClick = ev.getY();

		} else if (actionType == MotionEvent.ACTION_MOVE) {
			if (ev.getPointerCount() > 1) {
				startTimeForLongClick = 0;
			} else {
				float xmove = ev.getX();
				float ymove = ev.getY();
				xlow = xScreenCoordinateForLongClick - xtolerance;
				xhigh = xScreenCoordinateForLongClick + xtolerance;
				ylow = yScreenCoordinateForLongClick - ytolerance;
				yhigh = yScreenCoordinateForLongClick + ytolerance;
				if ((xmove < xlow || xmove > xhigh) || (ymove < ylow || ymove > yhigh)) {
					startTimeForLongClick = 0;
				}
			}

		} else if (actionType == MotionEvent.ACTION_UP) {
			long eventTime = ev.getEventTime();
			long downTime = ev.getDownTime();

			if (startTimeForLongClick == downTime) {
				if ((eventTime - startTimeForLongClick) > minMillisecondThresholdForLongClick) {
					float xup = ev.getX();
					float yup = ev.getY();
					xlow = xScreenCoordinateForLongClick - xtolerance;
					xhigh = xScreenCoordinateForLongClick + xtolerance;
					ylow = yScreenCoordinateForLongClick - ytolerance;
					yhigh = yScreenCoordinateForLongClick + ytolerance;
					if ((xup > xlow && xup < xhigh) && (yup > ylow && yup < yhigh)) {

						long totaltime = eventTime - startTimeForLongClick;
						String strtotaltime = Long.toString(totaltime);
						Log.d("long press detected: ", strtotaltime);

						Projection proj = mapView.getProjection();
						loc = proj.fromPixels((int) (ev.getX(ev.getPointerCount() - 1)), (int) (ev.getY(ev.getPointerCount() - 1)));
						lat = loc.getLatitudeE6();
						longitude = loc.getLongitudeE6();

						dialog = new Dialog(DrinkMapsActivity.this, R.style.DrinkDialogTheme);

						dialog.setContentView(R.layout.drink_detail);
						dialog.setTitle(getResources().getText(R.string.myDrinkPosition));
						dialog.setCancelable(true);
						eventName = (TextView) dialog.findViewById(R.id.title);
						eventDescription = (TextView) dialog.findViewById(R.id.snippet);
						ratingLabel = (TextView) dialog.findViewById(R.id.ratingLabel);
						eventRating = (RatingBar) dialog.findViewById(R.id.placeRating);

						updateButton = (Button) dialog.findViewById(R.id.updateButton);
						removeButton = (Button) dialog.findViewById(R.id.removeButton);

						ratingLabel.setVisibility(View.GONE);
						eventRating.setVisibility(View.GONE);
						removeButton.setVisibility(View.GONE);

						updateButton.setOnClickListener(new OnClickListener() {

							@Override
							public void onClick(View v) {
								boolean dateOk = true;

								String name = eventName.getText().toString();
								String description = eventDescription.getText().toString();

								if (dateOk) {
									double rating = (double) 0d;// placeRating.getRating();
									drinkDatabaseHelper.insertDrinkMapPoint(name + "", description + "", rating, lat / 1E6, longitude / 1E6);
									updateDrinkPoints();
									mapController.animateTo(loc);
									Toast.makeText(DrinkMapsActivity.this.getApplicationContext(), getResources().getText(R.string.placeInfoUpdatedToast), Toast.LENGTH_SHORT).show();
									dialog.dismiss();
								}
							}
						});
						dialog.show();
					}
				}
			}
		}
		return super.dispatchTouchEvent(ev);
	}

	public Location requestLocationProvider(LocationManager locationManager) {

		Location location = null;
		// if (locationManager != null &&
		// locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
		// locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
		// 3000L, 50.0f, DrinkMapsActivity.this);
		// location =
		// locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		// } else
		if (locationManager != null && locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
			locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1500L, 800.0f, DrinkMapsActivity.this);
			location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		}
		return location;
	}

	public void changeLocationProvider(LocationManager locationManager, String provider) {
		// if (locationManager != null &&
		// locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) &&
		// provider.equals(LocationManager.GPS_PROVIDER)) {
		// locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
		// 3000L, 50.0f, DrinkMapsActivity.this);
		// } else
		if (locationManager != null && locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) && provider.equals(LocationManager.NETWORK_PROVIDER)) {
			locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1500L, 800.0f, DrinkMapsActivity.this);
		}
	}

	private OverlayItem getMyPositionOverlayItem(Location location) {
		if (location != null) {
			lat = new Double(location.getLatitude() * 1e6).intValue();
			longitude = new Double(location.getLongitude() * 1e6).intValue();

			GeoPoint myPosPoint = new GeoPoint(lat, longitude);
			Date timeOfLocation = new Date(location != null ? location.getTime() : System.currentTimeMillis());
			return new OverlayItem(myPosPoint, getResources().getText(R.string.myPosition) + ": " + String.valueOf(location.getLatitude()).subSequence(0, 6) + " "
					+ String.valueOf(location.getLongitude()).subSequence(0, 6), getResources().getText(R.string.hereIAm).toString() + " @ " + timeOfLocation.getDate() + "."
					+ timeOfLocation.getMonth() + ". " + timeOfLocation.getHours() + ":" + timeOfLocation.getMinutes() + ":" + timeOfLocation.getSeconds());
		}
		return null;
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	public void onLocationChanged(Location location) {
		if (location != null && showCurrentLocation) {
			OverlayItem overlayItem = getMyPositionOverlayItem(location);
			if (overlayItem != null) {
				if (mapView.getOverlays().contains(myPositionOverlay))
					mapView.getOverlays().remove(myPositionOverlay);
				SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(DrinkMapsActivity.this);
				int backgroundId = Integer.parseInt(prefs.getString("BackgroundPref", "0"));
				Drawable myPositionSign = DrinkMapsActivity.this.getResources().getDrawable(BackgroundAdapter.getStyle(backgroundId).getCharIcon());
				myPositionOverlay = new LocationItemizedOverlay(myPositionSign, mapView.getContext());
				myPositionOverlay.addOverlay(overlayItem);
				mapView.getOverlays().add(myPositionOverlay);
				mapController.animateTo(overlayItem.getPoint());
				Toast.makeText(
						DrinkMapsActivity.this.getApplicationContext(),
						getResources().getText(R.string.myPosition) + ": " + String.valueOf(location.getLatitude()).subSequence(0, 6) + " " + String.valueOf(location.getLongitude()).subSequence(0, 6),
						Toast.LENGTH_SHORT).show();
			}
		}
	}

	@Override
	public void onProviderDisabled(String provider) {
		if (locationManager != null)
			changeLocationProvider(locationManager, provider);
	}

	@Override
	public void onProviderEnabled(String provider) {
		if (locationManager != null)
			changeLocationProvider(locationManager, provider);
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	private void updateDrinkPoints() {
		mapView = (MapView) this.findViewById(R.id.mapView);
		drinkDatabaseHelper = new DrinkPlaceHelper(getApplicationContext());

		if (mapView.getOverlays().contains(drinkPointsOverlay))
			mapView.getOverlays().remove(drinkPointsOverlay);
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(DrinkMapsActivity.this);
		int backgroundId = Integer.parseInt(prefs.getString("BackgroundPref", "0"));
		Drawable beerIcon = DrinkMapsActivity.this.getResources().getDrawable(BackgroundAdapter.getStyle(backgroundId).getPoiIcon());
		drinkPointsOverlay = new DrinkItemizedOverlay(beerIcon, mapView.getContext());
		ArrayList<DrinkPoint> drinkPoints = new ArrayList<DrinkPoint>();
		try {
			drinkPoints = drinkDatabaseHelper.getAllDrinkPoints();
		} catch (Exception ex) {
			Log.e(TAG, "Failed to read drink points", ex);
		}
		if (drinkPoints != null && drinkPoints.size() > 0) {
			for (DrinkPoint point : drinkPoints) {
				Double geoLat = point.getLatitude() * 1E6;
				Double geoLng = point.getLongitude() * 1E6;
				GeoPoint drinkPoint = new GeoPoint(geoLat.intValue(), geoLng.intValue());

				OverlayItem drinkOverlayItem = new OverlayItem(drinkPoint, String.valueOf(point.getId()), point.getSnippet());
				drinkPointsOverlay.addOverlay(drinkOverlayItem);
			}
			mapView.getOverlays().add(drinkPointsOverlay);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = this.getMenuInflater();
		inflater.inflate(R.menu.optionmenu, menu);
		MenuItem settings = menu.findItem(R.id.settings);
		settings.setIntent(new Intent(this, SettingsActivity.class));
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case R.id.exit:
			DrinkMapsActivity.this.finish();
			return true;
		case R.id.settings:
			Intent settingsIntent = item.getIntent();
			this.startActivityForResult(settingsIntent, 0);
			return true;
		case android.R.id.home:
			// Toast.makeText(DrinkManagerListActivity.this.getApplicationContext(),
			// getResources().getText(R.string.alreadyToast),
			// Toast.LENGTH_SHORT).show();
			Intent intent = new Intent(this, DrinkManagerListActivity.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
			return true;
		case R.id.drinks:
			Intent drinksIntent = new Intent(getApplicationContext(), DrinkManagerListActivity.class);
			this.startActivityForResult(drinksIntent, 0);
			return true;
		case R.id.places:
			Intent placesIntent = new Intent(getApplicationContext(), DrinkPlacesActivity.class);
			this.startActivityForResult(placesIntent, 0);
			return true;
		case R.id.custom:
			Intent customIntent = new Intent(this, CustomDrinksActivity.class);
			this.startActivityForResult(customIntent, 0);
			// Toast.makeText(getApplicationContext(),
			// getResources().getText(R.string.alreadyToast),
			// Toast.LENGTH_SHORT).show();
			return true;
		case R.id.history:
			Intent historyIntent = new Intent(this, DrinkHistoryActivity.class);
			this.startActivityForResult(historyIntent, 0);
			// Toast.makeText(getApplicationContext(),
			// getResources().getText(R.string.alreadyToast),
			// Toast.LENGTH_SHORT).show();
			return true;
		case R.id.graphs:
			Intent graphsIntent = new Intent(this, DrinkGraphActivity.class);
			this.startActivityForResult(graphsIntent, 0);
			// Toast.makeText(getApplicationContext(),
			// getResources().getText(R.string.alreadyToast),
			// Toast.LENGTH_SHORT).show();
			return true;
		case R.id.back:
			Intent backIntent = new Intent(getApplicationContext(), BackgroundChooserActivity.class);
			this.startActivityForResult(backIntent, 0);
			return true;
		case R.id.map:
			Toast.makeText(DrinkMapsActivity.this.getApplicationContext(), getResources().getText(R.string.alreadyToast), Toast.LENGTH_SHORT).show();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	protected void onResume() {
		updateDrinkPoints();
		super.onResume();
		BackgroundAdapter.updateBackgroundFromPrefs(prefs, this);

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		locationManager.removeUpdates(this);
	}
}
